<?php

namespace APP\Repository;

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/2/26
 * Time: 16:48
 */

use Illuminate\Support\Facades\DB;
use Log;
use Maatwebsite\Excel\Facades\Excel;

class BaseRepository
{
    public function __construct()
    {
        // 开启 log
        DB::connection()->enableQueryLog();
    }

    //统一返回的字段  在这个地方返回的都是 2***********
    public function returnMsg($code = 200, $msg = '', $data = [], $coun = 0)
    {
        // if ($code != 200) {
        //   $code = 20000 + $code;
        // }
        //有人调用这个地方的时候 如果返回错误 直接返回
        return [
            'code' => $code ?: 200,
            'msg' => $msg ?: '成功',
            'data' => $data ?: [],
            'count' => $coun ?: 0
        ];
    }

    /**
     * 过滤前端的参数，得到自己真正需要的参数  错误的话 返回错误信息
     * @param $request  Request对象
     * @param array $mustFields 必填字段
     * @param array $editFields 可选字段
     * @param array $msgField 必填字段对应返回错误信息
     * @return array
     */
    public function getRealData($request, $mustFields = array(), $optionalFields = array(), $msgField = array())
    {
        $values = array();

        $editFields = array_unique(array_merge($mustFields, $optionalFields));

        //没有字段
        if (!$editFields) {
            return '参数不能为空';
        }

        //验证必填字段
        foreach ($mustFields as $field) {
            if (!(isset($request[$field]) && $request[$field] !== '')) {
                $msg = '参数错误';
                if (!empty($msgField[$field])) {
                    $msg = $msgField[$field];
                }
                return $msg;
            }
        }

        //格式化可选字段的传参
        foreach ($editFields as $field) {
            if (isset($request[$field])) {
                if (is_array($request[$field])) {
                    $values[$field] = $request[$field];
                } else {
                    $values[$field] = trim($request[$field]);
                }
            }
            // if(isset($request[$field]) && is_array($request[$field])){
            //   $values[$field] = ($request[$field]);
            // }
        }
        return $values;
    }

    /**
     * 打印最后一条sql语句
     */
    public function getLastSql($isAll = false)
    {
        $queries = DB::getQueryLog();
        if ($isAll) {
            return $queries;
        }
        $a = end($queries);
        $tmp = str_replace('?', '"' . '%s' . '"', $a["query"]);

        return vsprintf($tmp, $a['bindings']);
    }

    public function getWhere($where = array(), $request)
    {
        $cron = array(); //$request->has($v);//查询字段
        foreach ($where as $v) {
            if (isset($request[$v]) && $request[$v] !== '') {
                $cron[$v] = trim($request[$v]);
            }
        }
        return $cron;
    }


    /**
     * 查询语句
     */
    public function search($model, $cron, $page = 1, $limit = 10)
    {
        //model 起别名
        if (isset($cron['alias']) && $cron['alias']) {
            $model = $model->aliasRable($cron['alias']);
        }
        //分表时 查询所有表
        if (isset($cron['sub_table']) && is_array($cron['sub_table'])) {
            $model = $model->searchAllSel($cron['sub_table'][0], $cron['sub_table'][1]);
        }
        if (isset($cron['raw']) && $cron['raw']) {
            $model = $model->whereRaw($cron['raw']);
        }
        if (isset($cron['where']) && $cron['where']) {
            $model = $model->where($cron['where']);
        }
        if (isset($cron['whereor']) && $cron['whereor']) {
            $a = $cron['whereor'];
            $model = $model->where(function ($query) use ($a) {
                $query->where($a['where'])->orWhere($a['whereor']);
            });
        }
        if (isset($cron['whereors']) && $cron['whereors']) {
            $a = $cron['whereors'];
            $model = $model->where(function ($query) use ($a) {
                $query->where($a['where'])->orWhere($a['whereor']);
            });
        }
        if (isset($cron['In']) && $cron['In']) {
            foreach ($cron['In'] as $k => $v)
                $model = $model->whereIn($k, $v); //whereNotIn
        }
        if (isset($cron['nIn']) && $cron['nIn']) {
            foreach ($cron['nIn'] as $k => $v)
                $model = $model->whereNotIn($k, $v); //
        }
        if (isset($cron['eq']) && $cron['eq']) {
            foreach ($cron['eq'] as $k => $v)
                $model = $model->where($k, '=', $v);
        }
        if (isset($cron['neq']) && $cron['neq']) {
            foreach ($cron['neq'] as $k => $v)
                $model = $model->where($k, '!=', $v);
        }
        if (isset($cron['egt']) && $cron['egt']) {
            foreach ($cron['egt'] as $k => $v) {
                $model = $model->where($k, '>=', $v);
            }
        }
        if (isset($cron['elt']) && $cron['elt']) {
            foreach ($cron['elt'] as $k => $v) {
                $model = $model->where($k, '<=', $v);
            }
        }
        if (isset($cron['between']) && $cron['between']) {
            foreach ($cron['between'] as $k => $v) {
                $model = $model->whereBetween($k, $v);
            }
        }
        if (isset($cron['like']) && $cron['like']) //此数据可以配配用户串
        {
            $model = $model->where(function ($query) use ($cron) {
                foreach ($cron['like'] as $lk => $lv)
                    $query->where($lk, 'like', '%' . $lv . '%');
            });
        }
        if (isset($cron['liker']) && $cron['liker']) {
            $model = $model->where(function ($query) use ($cron) {
                foreach ($cron['liker'] as $lk => $lv)
                    $query->where($lk, 'like', $lv);
            });
        }
        if (isset($cron['likeor']) && $cron['likeor']) {
            $model = $model->where(function ($query) use ($cron) {
                foreach ($cron['likeor'] as $lk => $lv)
                    $query->orWhere($lk, 'like', $lv);
            });
        }
        if (isset($cron['likeorall']) && $cron['likeorall']) {

            foreach ($cron['likeorall'] as $lk => $lv) {
                $model = $model->where(function ($query) use ($lk, $lv) {
                    if (is_array($lv)) {
                        // $query->orWhere($lk, 'like', $lv);
                        foreach ($lv as $kl1 => $vl1) {
                            $query->orWhere($lk, 'like', '%' . $vl1 . '%');
                        }
                    }
                    if (is_string($lv)) {
                        $query->orWhere($lk, 'like', $lv);
                    }
                });
            }


        }
        if (isset($cron['select'])) $model = $model->select($cron['select']);
        if (isset($cron['join']) && $cron['join']) {
            foreach ($cron['join'] as $lk => $v) {
                $model = $model->leftJoin($v['table'], $v['table'] . '.' . $v['left'], '=', $v['right']);
            }
        }
        // var_dump($model);
        // DB::connection()->enableQueryLog();
        $count = $model->count();
        // $res = $this->getlastSql();
        // var_dump($res, 6666);
        // Log::info($this->getlastSql());
        if (isset($cron['exports']) && $cron['exports'] == 1) return $model;


        if (isset($page) && isset($limit) && empty($cron['limit'])) {
            $start = 0;
            if ($page >= 1) {
                $start = ((int)$page - 1) * (int)$limit;
            }
            $model = $model->skip($start)->take($limit);
        }

        if (isset($cron['limit']) && $cron['limit'] && $cron['limit']['start'] != -1) {
            if (empty($cron['limit']['number'])) {
                $cron['limit']['number'] = 10;
            }
            if ($cron['limit']['start'] < 0) {
                $cron['limit']['start'] = 0;
            }
            $model = $model->skip($cron['limit']['start'])->take($cron['limit']['number']);
        }
        if (isset($cron['order']) && $cron['order']) {
            if (is_array($cron['order']['orderby'])) {
                foreach ($cron['order']['orderby'] as $key => $v) {
                    // var_dump($key);
                    $model = $model->orderBy($key, $v);
                }
            } else {
                $model = $model->orderBy($cron['order']['orderby'], $cron['order']['orderdir']);
            }
        } else {
            $model = $model->orderBy('id', 'desc');
        }

        // DB::connection()->enableQueryLog();
        $sel = $model->get()->toArray();
        // $res = $this->getlastSql();
        // var_dump($res, 6666);
        return $this->returnMsg(200, '查询成功', $sel, $count);
    }

    public function search2($model, $cron, $money = '')
    {

        if (isset($cron['where']) && $cron['where']) {
            $model = $model->where($cron['where']);
        }
        if (isset($cron['In']) && $cron['In']) {
            foreach ($cron['In'] as $k => $v)
                $model = $model->whereIn($k, $v); //whereNotIn
        }
        if (isset($cron['nIn']) && $cron['nIn']) {
            foreach ($cron['nIn'] as $k => $v)
                $model = $model->whereNotIn($k, $v); //
        }
        if (isset($cron['neq']) && $cron['neq']) {
            foreach ($cron['neq'] as $k => $v)
                $model = $model->where($k, '!=', $v);
        }
        if (isset($cron['between']) && $cron['between']) {
            foreach ($cron['between'] as $k => $v)
                $model = $model->whereBetween($k, $v);
        }
        if (isset($cron['like']) && $cron['like']) //此数据可以配配用户串
        {
            $model = $model->where(function ($query) use ($cron) {
                foreach ($cron['like'] as $lk => $lv)
                    $query->where($lk, 'like', '%' . $lv . '%');
            });
        }
        if (isset($cron['liker']) && $cron['liker']) {
            $model = $model->where(function ($query) use ($cron) {
                foreach ($cron['liker'] as $lk => $lv)
                    $query->where($lk, 'like', $lv);
            });
        }
        if (isset($cron['likeor']) && $cron['likeor']) {
            $model = $model->where(function ($query) use ($cron) {
                foreach ($cron['likeor'] as $lk => $lv)
                    $query->orWhere($lk, 'like', $lv);
            });
        }
        if (isset($cron['join']) && $cron['join']) {
            foreach ($cron['join'] as $lk => $v) {
                $model = $model->leftJoin(Prefix . $v['table'], Prefix . $v['table'] . '.' . $v['left'], '=', $v['right']);
            }
        }

        $num = $model->select(DB::raw("sum({$money}) as money"))->first();
        $money = isset($num->money) ? $num->money : 0;

        return $money;
    }
//  以下以unified开头的都是统一模式处理方法，可以减少curd的代码量
//  列表内容
    public function unifiedIndex($where = [])
    {
        $pk = $this->model->getKeyName();
        if (!isset($where['order'])) {
            $where['order'] = ['orderby' => $pk, 'orderdir' => 'desc'];
        }
        $data = $this->search($this->model, $where);
//        echo $this->getLastSql();
//        if (!empty($data['data'])) {
//            $data['data'] = usfirstArr($data['data']);
//        }
        return $data;
    }

    //删除
    public function unifiedDel($id, $shopId = 0)
    {
        if (empty($id)) {
            return $this->returnMsg(1, "没有指明数据");
        }
        $pk = $this->model->getKeyName();
        if (strpos($id, ',') > 0) {
            $id = explode(',', $id);
        }
        if (is_array($id)) {
            $where = [[$pk, "in", $id]];
        } else {
            $where = [$pk => $id];
        }
        if ($shopId > 0) {
            $where['shop_id'] = $shopId;
        }
        $result = $this->model->where($where)->count();
        if ($result) {
            $del = $this->model->where($where)->delete();
            return $this->returnMsg(200, "删除成功");
        }
        return $this->returnMsg(1, "数据不存在");
    }

//    修改状态
    public function unifiedUpdateStatus($id, $status, $shopId = 0)
    {
        if (!in_array($status, [0, 1])) {
            return $this->returnMsg(3, '状态值异常');
        }
        $pk = $this->model->getKeyName();
        $updateData = ["status" => $status];
        $where = [
            $pk => $id
        ];
        if ($shopId > 0) {
            $where['shop_id'] = $shopId;
        }
        $res = $this->model->where($where)->update($updateData);
        if (false !== $res) {
            return $this->returnMsg(200, '修改成功' . $this->getLastSql());
        }
        return $this->returnMsg(3, '请重新修改');
    }

    /**
     * 新增与编辑统一处理方法.
     * @param  $request
     * @param  $rulesFieldMsg
     * @param  $uniqueField
     * @return mixed
     */
    public function unifiedAdd($request, $rulesFieldMsg = [], $uniqueField = null, $shopId = 0)
    {
        return $this->unifiedEdit($request, $rulesFieldMsg, $uniqueField, $shopId);
    }

    public function unifiedEdit($request, $rulesFieldMsg = [], $uniqueField = null, $shopId = 0)
    {
        if (empty($request)) {
            return $this->returnMsg(2, '操作数据不能为空');
        }
        $createBy = $request['user']['id'] ?? 0;
        $pk = $this->model->getKeyName();
        $id = 0;
        $optionalFields = $this->model->getTableField();
        $mustField = [];
        if (!empty($rulesFieldMsg) && is_array($rulesFieldMsg)) {
            $mustField = array_keys($rulesFieldMsg);
        }
        $updateData = $this->getRealData($request, $mustField, $optionalFields, $rulesFieldMsg);

        if (!empty($updateData) && is_string($updateData)) {
            //返回错误参数
            return $this->returnMsg(
                2,
                $updateData
            );
        }
        if (isset($updateData[$pk]) && $updateData[$pk] > 0) {
            $id = $updateData[$pk];
        }
//        唯一字段判断
        if (!empty($uniqueField)) {
            $where = [[$uniqueField, '=', $updateData[$uniqueField]]];
            if ($id > 0) {
                $where = [[$uniqueField, '=', $updateData[$uniqueField]], [$pk, '!=', $id]];
            }
            $isTrue = $this->model->where($where)->count($pk);
            if ($isTrue) {
                return $this->returnMsg(1, $uniqueField . '内容已经存在');
            }
        }
        if ($id > 0) {
//            修改内容
            $where = [$pk => $id];
            if ($shopId > 0) {
                $where['shop_id'] = $shopId;
            }
            $haveData = $this->model->where($where)->count($pk);
            if (!$haveData) {
                return $this->returnMsg(101, '未查询到修改的数据' . $this->getLastSql());
            }
            if (in_array('updated_at', $optionalFields)) {
                $updateData['updated_at'] = date('Y-m-d H:i:s');
            }
            unset($updateData[$pk]);
            $res = $this->model->where($where)->update($updateData);
            if (false !== $res) {
                return $this->returnMsg(200, '修改成功');
            } else {
                return $this->returnMsg(20, '修改错误');
            }
        } else {
//            新增
            if (in_array('created_by', $optionalFields)) {
                $updateData['created_by'] = $createBy;
            }
            if (in_array('created_at', $optionalFields)) {
                $updateData['created_at'] = date('Y-m-d H:i:s');
            }
            if ($shopId > 0 && in_array('shop_id', $optionalFields)) {
                $updateData['shop_id'] = $shopId;
            }
            $id = $this->model->insertGetId($updateData);
            if ($id > 0) {
                $updateData[$pk] = $id;
                return $this->returnMsg(200, '添加成功', $updateData);
            }
            return $this->returnMsg(3, '内容保存异常');
        }
    }

    //查看
    public function unifiedGetPage($where = [], $page = 1, $limit = 10, $field = ['*'], $orderBy = null)
    {
        $pk = $this->model->getKeyName();
        //        先要总数
        $totalRows = 0;
        if ($page == 1) {
            $totalRows = $this->model->searchWhere($where)->count($pk);
        }
        $model = $this->model->searchWhere($where)->select($field)->page($page, $limit);
        if (!empty($orderBy) && is_array($orderBy)) {
            foreach ($orderBy as $k => $v) {
                $model->orderBy($k, $v);
            }
        } else {
            $model->orderByDesc($pk);
        }
        $rows = $model->get();
        return $this->returnMsg(200, '查询成功', $rows, $totalRows);
    }

    //查询 单条数据
    public function unifiedGetOne($where, $field = ['*'])
    {
        $pk = $this->model->getKeyName();
        return $this->model->where($where)->select($field)->orderBy($pk, 'desc')->first();
    }

    public function unifiedGetAll($where, $field = ['*'], $orderBy = null)
    {
        $pk = $this->model->getKeyName();
        if (empty($orderBy)) {
            $orderBy = [$pk => "desc"];
        }
        $model = $this->model->searchWhere($where)->select($field);
        if (!empty($orderBy) && is_array($orderBy)) {
            foreach ($orderBy as $k => $v) {
                $model->orderBy($k, $v);
            }
        } else {
            $model->orderByDesc($pk);
        }
        return $model->get();
    }

    public function unifiedUpdate($where, $updateData = [])
    {
        if (!empty($updateData)) {
            return $this->model->where($where)->update($updateData);
        }
        return false;
    }

    public function setHtmlUploadPicHost($html, $host = null)
    {
        if (empty($host)) {
            $host = $_SERVER['HTTP_HOST'];
        }
        $html = str_replace('src= ', 'src=', $html);
        $html = str_replace('src =', 'src=', $html);
        $html = str_replace('src = ', 'src=', $html);
        $html = str_replace('//', '/', html_entity_decode($html));

        $html = str_replace('src="/attach/', 'src="http://' . $host . '/attach/', $html);
        $html = str_replace("src='/attach/", "src='http://" . $host . '/attach/', $html);
        $html = str_replace("src=/attach/", "src=http://" . $host . '/attach/', $html);

        return rawurlencode($html);
    }
}
